package homework03_reference;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

public class GeneratePerson_3 {
	private static final String BLANK = " ";
	private static final String TAB = "\t";
	private StringBuilder sb = new StringBuilder();

	public static void main(String[] args) {
		GeneratePerson_3 gp = new GeneratePerson_3();
		gp.generate();
	}

	/*
	 * private void testModifier(){ System.out.println(Modifier.PUBLIC);//1
	 * System.out.println(Modifier.PRIVATE);//2
	 * System.out.println(Modifier.PROTECTED);//4
	 * System.out.println(Modifier.INTERFACE);// }
	 */

	private static Class<?> clazz = null;
	static {

		String NameOfPersonJava = "homework03.Person";
		try {
			clazz = Class.forName(NameOfPersonJava);
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	public void generate() {
		this.getPackageDesc();
		this.getClassDesc();
		this.getFieldDesc();
		this.getConstructorDesc();
		this.getMethodDesc();
		sb.append("\n}");
		this.generateOutput();
	}

	private void getPackageDesc() {
		String packageName = clazz.getPackage().getName();
		sb.append("package " + packageName + ".generated;");
	}

	/**
	 * Modifier类修饰符的对应情况 Modifier.PUBLIC //1 Modifier.PRIVATE//2
	 * Modifier.PROTECTED//4 "default"//0 modifier值>=512即为interface，0-511是class
	 */
	private void getClassDesc() {
		String classModifier = "";
		int modifier = clazz.getModifiers();
		if (modifier == 0) {
			classModifier = "class";
		} else if (modifier == 1) {
			classModifier = "public class";
		} else {
			if (Modifier.isPublic(modifier)) {
				classModifier = "public interface";
			} else {
				classModifier = "interface";
			}
		}
		String className = clazz.getSimpleName();
		sb.append("\n\n" + classModifier + BLANK + className + "{");
	}

	private void getConstructorDesc() {
		@SuppressWarnings("rawtypes")
		Constructor[] cons = clazz.getDeclaredConstructors();
		for (@SuppressWarnings("rawtypes")
		Constructor c : cons) {
			@SuppressWarnings("rawtypes")
			Class[] param = c.getParameterTypes();
			StringBuilder paramSB = new StringBuilder();
			// 有参数的方法，要在类型后面添加变量名
			if (param.length > 0) {
				paramSB.append(clazz.getSimpleName() + "(");
				String arg = "arg";
				for (int i = 0; i < param.length; i++) {
					paramSB.append(param[i].getCanonicalName() + BLANK + arg + i + ",");
				}
				paramSB = new StringBuilder(paramSB.substring(0, paramSB.length() - 1));
				paramSB.append(")");
				String name = c.toString();
				name = name.replaceFirst("\\S(\\w*\\.*)*\\((\\w*\\.*\\ *)*\\)", paramSB.toString());
				sb.append("\n" + TAB + name + "{\n\n" + TAB + "}\n");
				continue;
			}

			String name = c.toString();
			name = name.replaceFirst("\\S(\\w*\\.*)*\\(", clazz.getSimpleName() + "(");
			sb.append("\n" + TAB + name + "{\n\n" + TAB + "}\n");
		}
	}

	private void getFieldDesc() {
		Field[] field = clazz.getDeclaredFields();
		for (Field f : field) {
			String name = f.toString();
			name = name.replaceFirst("\\S(\\w*\\.*)*$", f.getName());
			sb.append("\n" + TAB + name + ";");
		}
		sb.append("\n");
	}

	private void getMethodDesc() {
		Method[] method = clazz.getDeclaredMethods();
		for (Method m : method) {
			Class[] param = m.getParameterTypes();
			StringBuilder paramSB = new StringBuilder();
			// 有参数的方法，要在类型后面添加变量名
			if (param.length > 0) {
				paramSB.append(m.getName() + "(");
				String arg = "arg";
				for (int i = 0; i < param.length; i++) {
					paramSB.append(param[i].getCanonicalName() + BLANK + arg + i + ",");
				}
				paramSB = new StringBuilder(paramSB.substring(0, paramSB.length() - 1));
				paramSB.append(")");
				String name = m.toString();
				name = name.replaceFirst("\\S(\\w*\\.*)*\\((\\w*\\.*\\ *)*\\)", paramSB.toString());
				sb.append("\n" + TAB + name + "{\n\n" + TAB + "}\n");
				continue;
			}

			String name = m.toString();
			name = name.replaceFirst("\\S(\\w*\\.*)*\\(", m.getName() + "(");
			// 获得return语句
			String attrName = StringUtil_3.firstCharToLower(m.getName().substring(3));
			paramSB.append("\n" + TAB + TAB + "return " + attrName + ";");

			sb.append("\n" + TAB + name + "{");
			sb.append(paramSB.toString() + "\n" + TAB + "}\n");
		}
	}

	private void generateOutput() {
		String path = clazz.getPackage().getName();
		path = path.replace(".", "\\");
		String url = System.getProperty("user.dir") + "\\src\\" + path + "\\generated\\" + clazz.getSimpleName()
				+ ".java";
		FileOutputStream fileWriter;
		try {
			fileWriter = new FileOutputStream(url);
			fileWriter.write(sb.toString().getBytes("UTF-8"));
			fileWriter.flush();
			fileWriter.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

}
